﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RiskMan.Config;
using RiskMan.DataClass.Models;
using RiskMan.DataClass.Models.Quik;
using RiskMan.DataClass.Models.RM;
using RiskMan.Views.Dialogs;
using System.Reflection;

namespace RiskMan.Views.LimitStock
{
    class LogicLimit
    {
        private PositionModel positionModel;
        private MainWindow mainWindow;
        private string _formate;
        public static string logLimitStock;

        #region Конструкторы

        /// <summary>
        /// конструктор для Remove()
        /// </summary>
        /// <param name="seccode"></param>
        /// <param name="mianWindow"></param>
        public LogicLimit(PositionModel positionModel, MainWindow mianWindow)
        {
            this.positionModel = positionModel;
            this.mainWindow = mianWindow;
            logLimitStock = null;
        }

        /// <summary>
        /// конструктор для Start()
        /// </summary>
        /// <param name="positionModel"></param>
        /// <param name="mainWindow"></param>
        /// <param name="_formate"></param>
        public LogicLimit(PositionModel positionModel, MainWindow mainWindow, string _formate)
        {
            this.positionModel = positionModel;
            this.mainWindow = mainWindow;
            this._formate = _formate;
            logLimitStock = null;
        }

        #endregion


        /// <summary>
        /// Начало обработки лимитов по текущим позициям
        /// </summary>
        public void Start()
        {
            foreach (var item in mainWindow._dataProvider.LimitStockList)
            {
                if (item.ClientCode == positionModel.ClientCode && item.Seccode == positionModel.Seccode)
                {

                    // обработка режимов 
                    if (positionModel.Count != 0)
                        if (((item.Regim == "Лонг" && positionModel.Count < 0) || (item.Regim == "Шорт" && positionModel.Count > 0)) && positionModel.MessageRegim == false)
                        {
                            positionModel.MessageRegim = true;
                            //new DialogMessage("По счету " + item.ClientCode + " торговля в не разрешенную сторону по инстументу " + item.Seccode + ". Текущий лимит "
                              //  + positionModel.Count + ", установленный режим " + item.Regim, "Лимиты по бумагам");
                            cfg.SetLog("Лимиты по бумагам. По счету " + item.ClientCode + " торговля в не разрешенную сторону по инстументу " + item.Seccode + ". Текущий лимит "
                                + positionModel.Count + ", установленный режим " + item.Regim, mainWindow.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
                            logLimitStock = DateTime.Now + " По счету " + item.ClientCode + " торговля в не разрешенную сторону по инстументу " + item.Seccode + ". Текущий лимит "
                                + positionModel.Count + ", установленный режим " + item.Regim;
                        }

                    if (((item.Regim == "Лонг" && positionModel.Count >= 0) || (item.Regim == "Шорт" && positionModel.Count <= 0) || (item.Regim == "Лонг/Шорт" && Math.Abs(positionModel.Count) <= Math.Abs(positionModel.Count))) && positionModel.MessageRegim == true)
                        positionModel.MessageRegim = false;

                    // обработка лимитов по инструментов 
                    if (item.LimitStock < Math.Abs(positionModel.Count))
                    {
                        if (positionModel.Message == false)
                        {
                            positionModel.Message = true;
                            new DialogMessage("По счету " + item.ClientCode + " Превышен объем по инструменту " + item.Seccode + ". Текущий лимит "
                                + positionModel.Count + ", установленные лимиты " + item.LimitStock, "Лимиты по бумагам");
                            cfg.SetLog("Лимиты по бумагам. По счету " + item.ClientCode + " Превышен объем по инструменту " + item.Seccode + ". Текущий лимит "
                                + positionModel.Count + ", установленные лимиты " + item.LimitStock, mainWindow.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
                            logLimitStock = DateTime.Now + " По счету " + item.ClientCode + " Превышен объем по инструменту " + item.Seccode + ". Текущий лимит "
                                + positionModel.Count + ", установленные лимиты " + item.LimitStock;
                        }
                        //закрытие позиции при превышении лимита
                        if (item.IsAllowClose == true)
                        {
                            if (item.Status == "unknown")
                            {
                                item.Status = ChangeStatusOrder(item.ID, item.Account, item.ClientCode);
                                if (item.TimeSend < (DateTime.Now - new TimeSpan(0, 0, 10)))
                                {
                                    item.Status = null;
                                    item.ID = 0;
                                }

                            }

                            if (item.Status == cfg.Performed)
                            {
                                if (item.TimeSend < (DateTime.Now - new TimeSpan(0, 0, 3)))
                                {
                                    item.Status = null;
                                    item.ID = 0;
                                }                         
                            }

                            if (item.Status == null)
                                if (item.Account == item.ClientCode)
                                {
                                    char operation = '\0';
                                    int quantity = 0;
                                    GetQuantityAndOperation(item, ref operation, ref quantity);

                                    item.ID = mainWindow.Terminals.SendOrder
                                        (
                                            item.Account,
                                            item.ClientCode,
                                            operation,
                                            mainWindow._dataProvider.GetMaxMinPrice(item.Seccode, operation == 'S' ? 'B' : 'S'),
                                            quantity,
                                            item.Seccode,
                                            mainWindow._dataProvider.GetClasscode(item.Seccode)
                                        );
                                    item.Status = "unknown";
                                    item.TimeSend = DateTime.Now;
                                }
                                else
                                {
                                    char operation = '\0';
                                    int quantity = 0;

                                    GetQuantityAndOperation(item, ref operation, ref quantity);

                                    item.ID = mainWindow.Terminals.SendMMMarketID
                                    (
                                        item.Account,
                                        item.ClientCode,
                                        operation,
                                        quantity,// mainWindow._dataProvider.GetLots(item.Seccode)
                                        item.Seccode,
                                        mainWindow._dataProvider.GetClasscode(item.Seccode),
                                        "LS"
                                    );
                                    item.Status = "unknown";
                                    item.TimeSend = DateTime.Now;
                                }

                        }
                    }
                    if (item.LimitStock >= Math.Abs(mainWindow._dataProvider.GetCurPosition(item.Seccode, item.Account, item.ClientCode)) && positionModel.Message == true)
                        positionModel.Message = false;
                }
            }
        }

        private void GetQuantityAndOperation(ModuleLimitStockModel item, ref char operation, ref int quantity)
        {
            if (positionModel.Count > 0)
            {
                operation = 'S';
                quantity = Math.Abs(positionModel.Count - item.LimitStock);
            }
            if (positionModel.Count < 0)
            {
                operation = 'B';
                quantity = Math.Abs(positionModel.Count + item.LimitStock);
            }
        }


        internal void Inspection()
        {
            bool testLimitInstrumentToList = false;
            foreach (var item in mainWindow._dataProvider.LimitStockList)
                if (item.ClientCode == positionModel.ClientCode && item.Seccode == positionModel.Seccode && positionModel.Count != 0)
                    testLimitInstrumentToList = true;

            if (!testLimitInstrumentToList && positionModel.Message == false)
            {
                positionModel.Message = true;
                //new DialogMessage("По счету " + positionModel.ClientCode + " совершена операция по инструменту " + positionModel.Seccode
                //    + " не входящего в список разрешенных", "Лимиты по бумагам");
                cfg.SetLog("Лимиты по бумагам. По счету " + positionModel.ClientCode + " совершена операция по инструменту " + positionModel.Seccode
                    + " не входящего в список разрешенных", mainWindow.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
                logLimitStock = DateTime.Now + " По счету " + positionModel.ClientCode + " совершена операция по инструменту " + positionModel.Seccode
                    + " не входящего в список разрешенных";
            }
        }

        /// <summary>
        /// проверка по заявкам на изменения статуса
        /// </summary>
        private string ChangeStatusOrder(int ID, string _Account, string _ClientCode)
        {
            string result = "unknown";
            foreach (var item in mainWindow._dataProvider.GetOrderListAll(_Account, _ClientCode))
                if (item.Tid == ID)
                {
                    result = item.Status;
                    //CFG.SetLog("Изменение статуса заявки " + type + ": " + item.Status + " № заявки: " + item.Number +" Уровень: " +item.Price  ,mainWindow.ListBox_Logs);
                }
            return result;
        }
    }
}
